/********************************************************************
created:	2008/10/17
created:	17:10:2008
filename: 	qyAABB.h
author:		Xiong Jiayu
copyright:  
purpose:	
*********************************************************************/
#pragma once

#ifndef __QYPLANE_H__
#define __QYPLANE_H__

#include "qyMath.h"
#include "qyVector3.h"
#include "qyVector4.h"

#define PLANE_SIDE_FRONT	0
#define PLANE_SIDE_BACK		1
#define PLANE_SIDE_ON		2
#define PLANE_SIDE_CROSS	3

/*
===========================================
struct Plane

	plane with equation: a * x + b * y + c * z + d = 0
		-d is distance from origin to plane
===========================================
*/
struct Plane
{
	/*
	union
	{
		struct
		{
			Vector3	normal;	// plane normal
			float	d;	// signed distance from origin to the plane normal
		};
		struct
		{
			float a, b, c, d;
		};
	};
	*/
	float a, b, c, d;
	Plane( void );
	Plane( float a, float b, float c, float d );
	Plane( const Vector3 &normal, const float dist );
	Plane( const Plane &p );

	float			operator[]( const int index ) const;
	float &			operator[]( const int index );
	Plane			operator-() const;
	Plane &			operator=( const Plane &p );
	Plane			operator+( const Plane &p ) const;
	Plane			operator-( const Plane &p ) const;
	Plane &			operator*=( const Matrix3 &m );
	Plane			operator*( const Matrix3 &m ) const;

	bool			Compare( const Plane &p ) const;
	bool			Compare( const Plane &p, const float epsilon ) const;
	bool			Compare( const Plane &p, const float normalEpsilon, const float distEpsilon ) const;
	bool			operator==( const Plane &p ) const;
	bool			operator!=( const Plane &p ) const;

	void			Zero( void );
	void			SetNormal( const Vector3 &normal );
	const Vector3 &	Normal( void ) const;
	Vector3 &		Normal( void );
	float			Normalize();
	float			Dist( void ) const;
	void			SetDist( const float dist );
	void			Set( float a, float b, float c, float d );

	bool			FromPoints( const Vector3 &p1, const Vector3 &p2, const Vector3 &p3 );
	bool			FromPointsSlow( const Vector3 &p1, const Vector3 &p2, const Vector3 &p3 );
	bool			FromVector( const Vector3 &dir1, const Vector3 &dir2, const Vector3 &pos );
	void			FitThroughPoint( const Vector3 &p );

	Plane			Translate( const Vector3 &trans ) const;
	Plane &			TranslateSelf( const Vector3 &trans );
	Plane			Rotate( const Vector3 &orig, const Matrix3 &rot ) const;
	Plane &			RotateSelf( const Vector3 &orig, const Matrix3 &rot );

	float			DistanceFrom( const Vector3 &v ) const;
	int				Side( const Vector3 &v, const float epsilon = 0.0f ) const;

	bool			LineIntersection( const Vector3 &start, const Vector3 &end ) const;
	bool			LineIntersection( const Vector3 &start, const Vector3 &end, float &fraction ) const;
	bool			RayIntersection( const Vector3 &start, const Vector3 &dir, float &scale ) const;
	bool			PlaneIntersection( const Plane &plane, Vector3 &start, Vector3 &dir ) const;

	int				GetDimension( void ) const;

	const Vector4 &	ToVec4( void ) const;
	Vector4 &		ToVec4( void );
	const float *	ToFloatPtr( void ) const;
	float *			ToFloatPtr( void );
};

#include "qyPlane.inl"


#endif
